//
//  WCAAutoAddFirendManager.m
//  WeChatBuniess
//
//  Created by Guo Rui on 2017/12/25.
//  Copyright © 2017年 GR Harry. All rights reserved.
//

#import "WCAAutoMakeBookManager.h"
#import "YYModel.h"
#import "WCMokeListViewController.h"
#import "WCACotact.h"

//#define kContactCachePath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"TFWaitingContact.plist"]
#define kContactCachePath [@"/Users/guorui/Desktop/" stringByAppendingPathComponent:@"TFWaitingContact.plist"]

//#define kContactFailDataDictoryPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"TFFailData"]
#define kContactFailDataDictoryPath [@"/Users/guorui/Desktop/" stringByAppendingPathComponent:@"TFFailData"]

NSString * const WCAAutoMakeBookCompletionNotification = @"cn.timeface.wechatbuniess.makebookCompletionNotification";

@interface WCAAutoMakeBookManager()
@property (strong, nonatomic) NSMutableArray <WCACotact *> *waitingContact;
@property (strong, nonatomic) dispatch_queue_t queue;
@end

@implementation WCAAutoMakeBookManager

+ (instancetype)sharedInstance
{
    static WCAAutoMakeBookManager *mag = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        mag = [[WCAAutoMakeBookManager alloc] init];
        
    });
    return mag;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.queue = dispatch_queue_create("cn.timeface.wechatbuniess.wcaautomakebookmanager.queue", NULL);
        
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reciveMakeBookCompletion:) name:WCAAutoMakeBookCompletionNotification object:nil];
    }
    return self;
}

- (NSMutableArray *)waitingContact
{
    if (!_waitingContact) {
        NSFileManager *fileMag = [NSFileManager defaultManager];
        if ([fileMag fileExistsAtPath:kContactCachePath]) {
            _waitingContact = [NSMutableArray arrayWithCapacity:0];
            
            // 完成失败的没有必要加入到执行队列中
            for (WCACotact *c in [self getContactsFromDisk]) {
                if (c.tf_status != TFMakeBookStautsCompleteFail) {
                    [_waitingContact  addObject:c];
                }
            }
        }
        else {
            _waitingContact = [NSMutableArray arrayWithCapacity:0];
        }
    }
    return _waitingContact;
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - Public
- (void)addContact:(CPushContact *)contact
{
    dispatch_sync(self.queue, ^{
        NSLog(@"%@被加入到等待队列", contact.m_nsUsrName);
        WCACotact *c = [[WCACotact alloc] init];
        c.tf_status = TFMakeBookStautsUndo;
        c.contact = contact;
        [self.waitingContact addObject:c];
        [self startMakeBook];
        [self insertContact2Disk:c];
    });
    
}

- (void)check
{
    for (WCACotact *contact in self.waitingContact) {
        if (contact.tf_status == TFMakeBookStautsDoing) {
            NSLog(@"发现%@作书没有完成（正在作书状态），已被修改为undo状态", contact.contact.m_nsUsrName);
            contact.tf_status = TFMakeBookStautsUndo;
            dispatch_async(self.queue, ^{
                [self updateContacts2Disk:contact];
            });
        }
    }
    
    dispatch_sync(self.queue, ^{
        [self startMakeBook];
    });
    
}

#pragma mark - Private
- (void)startMakeBook
{
    if (self.waitingContact == nil || self.waitingContact.count == 0) {
        NSLog(@"等待队列中没有人员");
        return;
    }
    
    WCACotact *doingContact = nil;
    for (WCACotact *contact in self.waitingContact) {
        if (contact.tf_status == TFMakeBookStautsDoing) {
            doingContact = contact;
            break;
        }
    }
    
    if (doingContact == nil) {
        WCACotact *c = self.waitingContact.firstObject;
        c.tf_status = TFMakeBookStautsDoing;
        dispatch_async(self.queue, ^{
            [self updateContacts2Disk:c];
        });
        
        
        // 延迟的目的是让 控制器彻底释放
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            NSLog(@"%@.....正在作书", c.contact.m_nsUsrName);
            
            WCMokeListViewController *listVc = [[WCMokeListViewController alloc] init];
            listVc.contact = c.contact;
            UINavigationController *nvc = [[UINavigationController alloc] initWithRootViewController:listVc];
            [self.vc presentViewController:nvc animated:YES completion:nil];
        });
    }
    else {
        NSLog(@"队列中有正在作书的人员 - %@, 此时队列中情况 -%zd", doingContact.contact.m_nsUsrName, self.waitingContact.count);
    }
}

// 删除本地缓存
- (void)deleteContact2Disk:(WCACotact *)c
{
    NSMutableArray *dictMs = [NSMutableArray arrayWithContentsOfFile:kContactCachePath];
    
    if (dictMs == nil || dictMs.count == 0) {
        NSLog(@"删除 disk 上的 %@ 失败，因为disk没有缓存内容", c.contact.m_nsUsrName);
        return;
    }
    
    NSDictionary *destDict = nil;
    for (NSDictionary *dict_c in dictMs) {
        if ([dict_c[@"contact"][@"m_nsUsrName"] isEqualToString:c.contact.m_nsUsrName]) {
            destDict = dict_c;
        }
    }
    
    if (destDict) {
        [dictMs removeObject:destDict];
        [dictMs writeToFile:kContactCachePath atomically:YES];
    }
    else {
        NSLog(@"删除 disk 上的 %@ 失败，因为disk没有这个对象", c.contact.m_nsUsrName);
    }
}

// 插入本地缓存
- (void)insertContact2Disk:(WCACotact *)c
{
    NSMutableArray *dictMs = [NSMutableArray arrayWithContentsOfFile:kContactCachePath];
    if (dictMs == nil) {
        dictMs = [NSMutableArray arrayWithCapacity:0];
    }
    
    [dictMs addObject:[c yy_modelToJSONObject]];
    [dictMs writeToFile:kContactCachePath atomically:YES];
}

// 更新本地缓存
- (void)updateContacts2Disk:(WCACotact *)c
{
    NSMutableArray *dictMs = [NSMutableArray arrayWithContentsOfFile:kContactCachePath];
    
    if (dictMs == nil || dictMs.count == 0) {
        NSLog(@"更新 disk 上的 %@ 失败，因为disk没有缓存内容", c.contact.m_nsUsrName);
        return;
    }
    
    NSDictionary *destDict = nil;
    for (NSDictionary *dict_c in dictMs) {
        if ([dict_c[@"contact"][@"m_nsUsrName"] isEqualToString:c.contact.m_nsUsrName]) {
            destDict = dict_c;
        }
    }
    
    if (destDict) {
        // 删除旧的
        [dictMs removeObject:destDict];
        // 添加新的
        [dictMs addObject:[c yy_modelToJSONObject]];
        [dictMs writeToFile:kContactCachePath atomically:YES];
    }
    else {
        NSLog(@"更新 disk 上的 %@ 失败，因为disk没有这个对象", c.contact.m_nsUsrName);
    }
}


- (void)saveFailContactData2DiskWith:(WCACotact *)c failArray:(NSArray *)failArray
{
    c.tf_status = TFMakeBookStautsCompleteFail;
    
    if (failArray == nil || failArray.count == 0) {
        NSLog(@"%@ - 失败时数组为空", c.contact.m_nsUsrName);
        return;
    }
    
    NSFileManager *mag = [NSFileManager defaultManager];
    if ([mag fileExistsAtPath:kContactFailDataDictoryPath] == NO) {
        [mag createDirectoryAtPath:kContactFailDataDictoryPath withIntermediateDirectories:YES attributes:nil error:nil];
    }
    
    NSString *failFilePath = [kContactFailDataDictoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist", c.contact.m_nsUsrName == nil || c.contact.m_nsUsrName.length == 0 ? [NSDate date] : c.contact.m_nsUsrName]];
    
    c.tf_errorDataPath = failFilePath;
    [self updateContacts2Disk:c];
    
    dispatch_sync(dispatch_get_global_queue(0, 0), ^{
        [failArray writeToFile:failFilePath atomically:YES];
        NSLog(@"失败数据保存到 -%@", failFilePath);
    });
}

- (NSArray <WCACotact *>*)getContactsFromDisk
{
    __block NSArray *contactArray = nil;
    // 1. 获取字典数组
    NSArray *contactDictArray = [NSArray arrayWithContentsOfFile:kContactCachePath];
    // 2. 转换成CPushContact对象
    contactArray = [NSArray yy_modelArrayWithClass:[WCACotact class] json:contactDictArray].mutableCopy;
    
    return contactArray;
}

- (WCACotact *)getContact:(CPushContact *)pushContact
{
    WCACotact *destC = nil;
    for (WCACotact *c in self.waitingContact) {
        if ([c.contact.m_nsUsrName isEqualToString:pushContact.m_nsUsrName]) {
            destC = c;
            break;
        }
    }
    
    return destC;
}

#pragma mark - Actions
- (void)reciveMakeBookCompletion:(NSNotification *)notification
{
    NSDictionary *dict = notification.object;
    BOOL success = [[dict objectForKey:@"success"] boolValue];
    CPushContact *contact = [dict objectForKey:@"contact"];
    WCACotact *c = [self getContact:contact];
    
    if (!success) {
        NSArray *failArray = [dict objectForKey:@"failArray"];
        [self saveFailContactData2DiskWith:c failArray:failArray];
        

        NSLog(@"%@...作书完成失败", contact.m_nsUsrName);
        
        dispatch_sync(self.queue, ^{
//            [self updateContacts2Disk:contact];
            [self.waitingContact removeObject:c];
            [self startMakeBook];
        });
    }
    else {
        NSLog(@"%@...作书完成成功", contact.m_nsUsrName);
        dispatch_sync(self.queue, ^{
            // 成功的时候，从磁盘和内存都删除
            [self deleteContact2Disk:c];
            [self.waitingContact removeObject:c];
            [self startMakeBook];
        });
        
    }
}




@end
